using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class SaveManager : MonoBehaviour
{
    public static SaveManager Instance { get; private set; }
    [SerializeField] private string fileName;
    [SerializeField] private bool encryptData;
    private GameData data;
    private List<ISavable> savableObjects;
    private FileDataHandler dataHandler;

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
            Destroy(gameObject);

        NewGame();
        dataHandler = new FileDataHandler(Application.persistentDataPath, fileName, encryptData);
        savableObjects = FindAllSavableObjects();
    }

    private void Start()
    {
        Load();
    }

    private void OnApplicationQuit()
    {
        Save();
    }

    public void Load()
    {
        data = dataHandler.Load();
        if (data == null)
        {
            NewGame();
        }
        foreach (ISavable savableObject in savableObjects)
        {
            savableObject.Load(data);
        }
    }

    public void Save()
    {
        foreach (ISavable savableObject in savableObjects)
        {
            savableObject.Save(ref data);
        }
        dataHandler.Save(data);
    }

    public void NewGame()
    {
        data = new();
    }

    private List<ISavable> FindAllSavableObjects()
    {
        IEnumerable<ISavable> allSavableObjects =
            FindObjectsByType<MonoBehaviour>(FindObjectsInactive.Include, FindObjectsSortMode.None).OfType<ISavable>();
        return allSavableObjects.ToList();
    }

#if UNITY_EDITOR
    [ContextMenu("Delete Save Data")]
#endif
    public void DeleteSaveData()
    {
        dataHandler = new FileDataHandler(Application.persistentDataPath, fileName, encryptData);
        dataHandler.Delete();
    }

    public bool HasSaveData()
    {
        return dataHandler.Load() != null;
    }
}